package com.samoiloff.util.actions {
	import com.samoiloff.util.events.ArrItemEvent;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;		

	/**
	 * @author Damirr
	 */
	public class Actions extends Action {
		
		protected var _arr		: Array;
		
		//private var _busy		: Boolean;
		private var _delayTimer : Timer;
		
		/*
		 * delay
		 */
		private var _delay	: int; //delay time in miliseconds
		public function get delay(): int { return _delay; }
		public function set delay(delay: int): void {
			_delay = delay;
			if (_delay > 0) {
				_delayTimer = new Timer(_delay, 1);
				_delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
			} else {
				clearDelayTimer();
				_delay = 0;
			}
		}
		
		public function Actions() {
			_arr = new Array();
		}
		
		private function onTimerComplete(e : TimerEvent) : void {
			getItemAt(0).start();
		}
		
		override public function destroy():void {
			clearDelayTimer();
			removeAllActions();
			
			super.destroy();
		}
		
		private function removeAllActions():void {
			var action:Action = getItemAt(0);

			if (action) {
				removeListeners(action);
			}
			
			for (var i : int = 0; i < length; i++) {
				action = getItemAt(i);
				action.destroy();
			}
			_arr = null;
		}
		
		private function clearDelayTimer():void {
			if (_delayTimer) {
				_delayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimerComplete);
				_delayTimer.stop();
				_delayTimer = null;
			}
		}
		
		public function addAction(actionItem : Action) : void {
			_arr.push(actionItem);
			dispatchEvent(new ArrItemEvent(ArrItemEvent.ITEM_ADD, actionItem));
		}
		
		public function removeAction(actionItem:Action):void {
			removeListeners(actionItem);
			
			var index: int = _arr.indexOf(actionItem);
			_arr.splice(index, 1);
			
			dispatchEvent(new ArrItemEvent(ArrItemEvent.ITEM_REMOVE, actionItem));
			actionItem.destroy();
		}

		override public function start() : void {
			if (!_started) {
				checkStart();
			}
		}
		
		protected function addListeners(actionItem : Action) : void {
			actionItem.addEventListener(ActionEvent.ACTION_COMPLETE, onActionComplete, false, -1);
			actionItem.addEventListener(ActionEvent.ACTION_CANCEL, onActionCanceled, false, -1);
		}
		
		protected function removeListeners(actionItem : Action):void {
			actionItem.removeEventListener(ActionEvent.ACTION_COMPLETE, onActionComplete);
			actionItem.removeEventListener(ActionEvent.ACTION_CANCEL, onActionCanceled);
		}

		protected function checkStart():void {
			if (length) {
				if (_started) {
					continueQueue();
				} else {
					startQueue();
				}
			} else {
				finish();
			}
		}
		
		private function startQueue() : void {
			_started = true;
			dispatchEvent(new ActionEvent(ActionEvent.ACTIONS_START, this));
			continueQueue();
		}
		
		private function continueQueue():void {
			var action : Action = getItemAt(0);
			addListeners(action);
			if (_delayTimer) {
				_delayTimer.start();
			} else {
				action.start();
			}
		}
		
		
		override protected function finish() : void {
			_started = false;
			dispatchEvent(new ActionEvent(ActionEvent.ACTIONS_COMPLETE, this));
		}
		
		
		private function onActionCanceled(e : Event) : void {
			if (_delayTimer) {
				_delayTimer.stop();
			}
			removeAllActions();
			_arr = [];
			dispatchEvent(new ActionEvent(ActionEvent.ACTIONS_CANCEL, this));
			checkStart();
		}
		
		protected function onActionComplete(e : Event) : void {
			if (_delayTimer) {
				_delayTimer.stop();
			}
			dispatchEvent(e);
			removeAction(getItemAt(0));
			checkStart();
		}
		
		public function get length() : int {
			return _arr.length;
		}
		
		public function getItemAt(i : int) : Action {
			return Action(_arr[i]);
		}
		
		
	}
}
